package com.shine.app.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;

import com.shine.app.R;

public class CardEditText extends EditText {
	private String[] text;
	private Integer length;
	private Integer totalLength;
	private Integer eachLength;
	private String delimiter;
	private String placeHolder;

	public CardEditText(Context context) {
		super(context);
	}

	public CardEditText(Context context, AttributeSet attrs) {
		super(context, attrs);
		try {
			TypedArray typedArray = context.obtainStyledAttributes(attrs,
					R.styleable.EditText);
			this.totalLength = 16;
			this.eachLength = 4;
			this.delimiter = " ";
			this.placeHolder = "0";
			typedArray.recycle();
			init();
			this.addTextChangedListener(new DivisionTextWatcher());
			this.setOnFocusChangeListener(new DivisionFocusChangeListener());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public CardEditText(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public void init() {
		int groupNum = 0;
		if (this.eachLength != 0) {
			groupNum = this.totalLength / this.eachLength;
		}
		length = this.totalLength + this.eachLength != 0 ? this.totalLength
				+ groupNum - 1 : 0;
		text = new String[this.length];
		if (length > 0) {
			for (int i = 0; i < length; i++) {
				if (i != 0 && (i + 1) % (this.eachLength + 1) == 0) {
					text[i] = this.delimiter;
				} else {
					text[i] = placeHolder;
				}
			}
			mySetText();
			mySetSelection();
		}
	}

	public String getResult() {
		StringBuffer buffer = new StringBuffer();
		for (String item : text) {
			if (!placeHolder.equals(item) && !delimiter.equals(item)) {
				buffer.append(item);
			}
		}
		return buffer.toString();
	}

	private class DivisionTextWatcher implements TextWatcher {

		@Override
		public void afterTextChanged(Editable s) {
		}

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count,
				int after) {
		}

		@Override
		public void onTextChanged(CharSequence s, int start, int before,
				int count) {
			if (s.length() < length) {
				int index = CardEditText.this.getSelectionStart();
				String deleteStr = text[index];
				if (delimiter.equals(deleteStr)) {
					index--;
				}
				text[index] = placeHolder;
				if (index - 1 >= 0) {
					if (delimiter.equals(text[index - 1])) {
						index--;
					}
				}
				mySetText();
				mySetSelection(index);
			}
			if (count == 1) {
				int index = isBlank(CardEditText.this.getSelectionStart());
				if (index != -1) {
					String allStr = s.toString();
					String inputStr = allStr.substring(start, start + count);
					text[index] = inputStr;
				}
				mySetText();
				mySetSelection();
			}
		}
	}

	private class DivisionFocusChangeListener implements OnFocusChangeListener {

		@Override
		public void onFocusChange(View v, boolean hasFocus) {
			if (hasFocus) {
				mySetSelection(0);
			}
		}
	}

	private void mySetText() {
		StringBuffer buffer = new StringBuffer();
		for (String item : text) {
			buffer.append(item);
		}
		setText(buffer);
	}

	private void mySetSelection() {
		mySetSelection(fullSelection());
	}

	private void mySetSelection(int index) {
		CardEditText.this.setSelection(index);
	}

	private int isBlank(int selection) {
		int index = -1;
		for (int i = selection - 1; i < length; i++) {
			if (placeHolder.equals(text[i])) {
				index = i;
				break;
			}
		}
		return index;
	}

	private int fullSelection() {
		int index = 0;
		for (int i = 0; i < length; i++) {
			if (!placeHolder.equals(text[i]) && !delimiter.equals(text[i])) {
				index = i + 1;
			}
		}
		return index;
	}

	public Integer getTotalLength() {
		return totalLength;
	}

	public void setTotalLength(Integer totalLength) {
		this.totalLength = totalLength;
	}

	public Integer getEachLength() {
		return eachLength;
	}

	public void setEachLength(Integer eachLength) {
		this.eachLength = eachLength;
	}

	public String getDelimiter() {
		return delimiter;
	}

	public void setDelimiter(String delimiter) {
		this.delimiter = delimiter;
	}

	public String getPlaceHolder() {
		return placeHolder;
	}

	public void setPlaceHolder(String placeHolder) {
		this.placeHolder = placeHolder;
	}

}
